﻿<?xml version="1.0" encoding="utf-8"?>
<!-- 
Network Configuration for a generic motorcar routing network
- This configuration incurs a runtime performance penalty by using the slower Script evaluators,
  but will work with more coordinate systems
  
OSM Tags:
    - highway:      motorcar navigable roads
    - maxspeed:     max road speed in kph (unless mph or mp/h is specified)
    - access:       road access restrictions
    - barrier:      motorcar barrier restrictions / drive time penalties
    - oneway:       turn restrictions onto oneway roads
    - surface:
    - smoothness:   drive time penalty for rough roads
    - contruct:
    - proposed:     restriction for roads in construction or proposed
    - maxheight:    vehicle height restriction (with routing paramater)
-->
<networkConfiguration>
    <edge>
        <name>roads</name>
        <connect_policy>AnyVertex</connect_policy>
        <osm_fields>
            <osm_field>access</osm_field>
            <osm_field>surface</osm_field>
            <osm_field>smoothness</osm_field>
            <osm_field>construct</osm_field>
            <osm_field>proposed</osm_field>
            <osm_field>maxheight</osm_field>
            <osm_field>maxspeed</osm_field>
            <osm_field>oneway</osm_field>
            <osm_field>name</osm_field>
        </osm_fields>
        <query>(highway IS NOT NULL) AND (LOWER(highway) in ('motorway','motorway_link','trunk','trunk_link','primary','primary_link','secondary','secondary_link','tertiary','tertiary_link','living_street','residential','unclassified','road'))</query>
        <street_name_fields>
            <direction_prefix></direction_prefix>
            <type_prefix></type_prefix>
            <street_name>osm_name</street_name>
            <direction_suffix></direction_suffix>
            <type_suffix></type_suffix>
        </street_name_fields>
    </edge>

    <junction>
        <name>barriers</name>
        <connect_policy>Override</connect_policy>
        <osm_fields>
            <osm_field>access</osm_field>
        </osm_fields>
        <query>(barrier IS NOT NULL) AND (LOWER(barrier) in ('block','bollard','chain','debris','jersey_barrier','lift_gate','log','spikes','swing_gate'))</query>
    </junction>

    <turn>
        <name>turns</name>
    </turn>

    <connectivity>
        <group>
            <source>roads</source>
            <source>barriers</source>
        </group>
    </connectivity>

    <directions>
        <length_attr>Length</length_attr>
        <length_units>Miles</length_units>
        <time_attr>DriveTime</time_attr>
    </directions>

    <network>
        <!-- Speed - descriptor -->
        <network_attribute>
            <name>Speed</name>
            <default_value>0</default_value>
            <descriptor>
                <datatype>double</datatype>
                <evaluator_attributes>
                    <source>roads</source>
                    <direction>From-To</direction>
                    <Field script_type="VBScript">
                        <expression>speed</expression>
                        <pre_logic>
                            <![CDATA[
                            speed = 0.0
                            If NOT IsNull([osm_maxspeed]) Then
                                strSpeed = Trim(LCase([osm_maxspeed]))
                                If IsNumeric(strSpeed) Then
                                    speed = CDbl(strSpeed)
                                ElseIf InStr(strSpeed, "mph") OR InStr(strSpeed, "mp/h") Then
                                    dim numSpeed
                                    For i = 1 to LEN(strSpeed)
                                        char = mid(strSpeed, i, 1)
                                        If IsNumeric(char) = True Then
                                            numSpeed = numSpeed & char
                                        Else
                                            Exit For
                                        End If
                                    Next

                                    If IsNumeric(numSpeed) Then
                                        speed = Round(CDbl(numSpeed) * 1.609344)
                                    End If
                                End If
                            End If

                            'Speed must not be 0 (division by 0)
                            If speed = 0 Then
                                speed = 0.001
                                Select Case LCase([highway])
                                    Case "motorway"
                                        speed = 110
                                    Case "motorway_link", "trunk"
                                        speed = 90
                                    Case "trunk_link", "primary"
                                        speed = 70
                                    Case "primary_link", "secondary"
                                        speed = 60
                                    Case "secondary_link", "tertiary"
                                        speed = 55
                                    Case "unclassified"
                                        speed = 50
                                    Case "tertiary_link"
                                        speed = 45
                                    Case "residential"
                                        speed = 40
                                    Case "living_street"
                                        speed = 10
                                End Select
                                
                                'Adjust speed for road surface
                                Select Case LCase([osm_surface])
                                    Case "compacted"
                                        speed = speed / 1.25
                                    Case "metal"
                                        speed = speed / 1.50
                                    Case "unpaved", "gravel", "fine_gravel", "pebblestone", "sand", "dirt", "grass"
                                        speed = speed / 2.00
                                End Select
                                
                                'Adjust for smoothness
                                Select Case LCase([osm_smoothness])
                                    Case "intermediate"
                                        speed = speed / 1.25
                                    Case "bad"
                                        speed = speed / 1.50
                                    Case "very_bad"
                                        speed = speed / 1.75
                                    Case "horrible"
                                        speed = speed / 2.00
                                    Case "very_horrible"
                                        speed = speed / 3.00
                                    Case "impassable"
                                        speed = speed / 5.00
                                End Select
                            End If
                            ]]>
                        </pre_logic>
                    </Field>
                </evaluator_attributes>
                <evaluator_attributes>
                    <source>roads</source>
                    <direction>To-From</direction>
                    <Field script_type="VBScript">
                        <expression>speed</expression>
                        <pre_logic>
                            <![CDATA[
                            speed = 0.0
                            If NOT IsNull([osm_maxspeed]) Then
                                strSpeed = Trim(LCase([osm_maxspeed]))
                                If IsNumeric(strSpeed) Then
                                    speed = CDbl(strSpeed)
                                ElseIf InStr(strSpeed, "mph") OR InStr(strSpeed, "mp/h") Then
                                    dim numSpeed
                                    For i = 1 to LEN(strSpeed)
                                        char = mid(strSpeed, i, 1)
                                        If IsNumeric(char) = True Then
                                            numSpeed = numSpeed & char
                                        Else
                                            Exit For
                                        End If
                                    Next

                                    If IsNumeric(numSpeed) Then
                                        speed = Round(CDbl(numSpeed) * 1.609344)
                                    End If
                                End If
                            End If

                            'Speed must not be 0 (division by 0)
                            If speed = 0 Then
                                speed = 0.001
                                Select Case LCase([highway])
                                    Case "motorway"
                                        speed = 110
                                    Case "motorway_link", "trunk"
                                        speed = 90
                                    Case "trunk_link", "primary"
                                        speed = 70
                                    Case "primary_link", "secondary"
                                        speed = 60
                                    Case "secondary_link", "tertiary"
                                        speed = 55
                                    Case "unclassified"
                                        speed = 50
                                    Case "tertiary_link"
                                        speed = 45
                                    Case "residential"
                                        speed = 40
                                    Case "living_street"
                                        speed = 10
                                End Select
                                
                                'Adjust speed for road surface
                                Select Case LCase([osm_surface])
                                    Case "compacted"
                                        speed = speed / 1.25
                                    Case "metal"
                                        speed = speed / 1.50
                                    Case "unpaved", "gravel", "fine_gravel", "pebblestone", "sand", "dirt", "grass"
                                        speed = speed / 2.00
                                End Select
                                
                                'Adjust for smoothness
                                Select Case LCase([osm_smoothness])
                                    Case "intermediate"
                                        speed = speed / 1.25
                                    Case "bad"
                                        speed = speed / 1.50
                                    Case "very_bad"
                                        speed = speed / 1.75
                                    Case "horrible"
                                        speed = speed / 2.00
                                    Case "very_horrible"
                                        speed = speed / 3.00
                                    Case "impassable"
                                        speed = speed / 5.00
                                End Select
                            End If
                            ]]>
                        </pre_logic>
                    </Field>
                </evaluator_attributes>
            </descriptor>
        </network_attribute>

        <!-- MaxHeight - descriptor -->
        <network_attribute>
            <name>MaxHeight</name>
            <default_value>0</default_value>
            <descriptor>
                <datatype>double</datatype>
                <evaluator_attributes>
                    <source>roads</source>
                    <direction>From-To</direction>
                    <Field script_type="VBScript">
                        <expression>maxHeight</expression>
                        <pre_logic>
                            <![CDATA[
                            maxHeight = 0.0
                            If IsNumeric( [osm_maxheight] ) Then
                                maxHeight = CDbl( [osm_maxheight] )
                            End If
                            ]]>
                        </pre_logic>
                    </Field>
                </evaluator_attributes>
                <evaluator_attributes>
                    <source>roads</source>
                    <direction>To-From</direction>
                    <Field script_type="VBScript">
                        <expression>maxHeight</expression>
                        <pre_logic>
                            <![CDATA[
                            maxHeight = 0.0
                            If IsNumeric( [osm_maxheight] ) Then
                                maxHeight = CDbl( [osm_maxheight] )
                            End If
                            ]]>
                        </pre_logic>
                    </Field>
                </evaluator_attributes>
            </descriptor>
        </network_attribute>

        <!-- DriveTime - cost -->
        <network_attribute>
            <name>DriveTime</name>
            <default_value>0</default_value>
            <cost useAsDefault="true">
                <units>Minutes</units>
                <datatype>double</datatype>
                <evaluator_attributes>
                    <source>roads</source>
                    <direction>From-To</direction>
                    <Script script_type="VBScript">
                        <expression>driveTime</expression>
                        <pre_logic>
                            <![CDATA[
                            'Speed must not be 0 (division by 0).
                            speed = Edge.AttributeValueByName("Speed")
                            If speed = 0 Then
                                speed = 0.001
                            End If

                            driveTime = (Edge.AttributeValueByName("Length") * 60) / (speed * 1000)
                            ]]>
                        </pre_logic>
                    </Script>
                </evaluator_attributes>
                <evaluator_attributes>
                    <source>roads</source>
                    <direction>To-From</direction>
                    <Script script_type="VBScript">
                        <expression>driveTime</expression>
                        <pre_logic>
                            <![CDATA[
                            'Speed must not be 0 (division by 0).
                            speed = Edge.AttributeValueByName("Speed")
                            If speed = 0 Then
                                speed = 0.001
                            End If

                            driveTime = (Edge.AttributeValueByName("Length") * 60) / (speed * 1000)
                            ]]>
                        </pre_logic>
                    </Script>
                </evaluator_attributes>
                <evaluator_attributes>
                    <source>barriers</source>
                    <direction>To-From</direction>
                    <Field script_type="VBScript">
                        <expression>driveTime</expression>
                        <pre_logic>
                            <![CDATA[
                            driveTime = 0
                            
                            Select Case LCase([highway])
                            Case "stop", "traffic_signals"
                                driveTime = driveTime + 0.1
                            End Select

                            Select Case LCase([barrier])
                            Case "toll_booth"
                                driveTime = driveTime + 0.1
                            End Select
                            ]]>
                        </pre_logic>
                    </Field>
                </evaluator_attributes>
            </cost>
        </network_attribute>

        <!-- Length - cost -->
        <network_attribute>
            <name>Length</name>
            <default_value>0</default_value>
            <cost useAsDefault="false">
                <units>Meters</units>
                <datatype>double</datatype>
                <evaluator_attributes>
                    <source>roads</source>
                    <direction>From-To</direction>
                    <Field script_type="VBScript">
                        <expression>[SHAPE]</expression>
                    </Field>
                </evaluator_attributes>
                <evaluator_attributes>
                    <source>roads</source>
                    <direction>To-From</direction>
                    <Field script_type="VBScript">
                        <expression>[SHAPE]</expression>
                    </Field>
                </evaluator_attributes>
            </cost>
        </network_attribute>

        <!-- Access - restriction -->
        <network_attribute>
            <name>Access</name>
            <default_value>false</default_value>
            <restriction useAsDefault="true">
                <evaluator_attributes>
                    <source>roads</source>
                    <direction>From-To</direction>
                    <Field script_type="VBScript">
                        <expression>restricted</expression>
                        <pre_logic>
                            <![CDATA[
                            restricted = False
                            Select Case [osm_access]
                                Case "no", "destination", "delivery", "agricultural", "forestry", "private"
                                    restricted = True
                            End Select
                            ]]>
                        </pre_logic>
                    </Field>
                </evaluator_attributes>
                <evaluator_attributes>
                    <source>roads</source>
                    <direction>To-From</direction>
                    <Field script_type="VBScript">
                        <expression>restricted</expression>
                        <pre_logic>
                            <![CDATA[
                            restricted = False
                            Select Case [osm_access]
                                Case "no", "destination", "delivery", "agricultural", "forestry", "private"
                                    restricted = True
                            End Select
                            ]]>
                        </pre_logic>
                    </Field>
                </evaluator_attributes>
                <evaluator_attributes>
                    <source>barriers</source>
                    <direction>From-To</direction>
                    <Field script_type="VBScript">
                        <expression>restricted</expression>
                        <pre_logic>
                            <![CDATA[
                            restricted = True
                            Select Case [osm_access]
                                Case "yes", "designated", "official", "permissive"
                                    restricted = False
                            End Select
                            ]]>
                        </pre_logic>
                    </Field>
                </evaluator_attributes>
            </restriction>
        </network_attribute>

        <!-- Closed - restriction -->
        <network_attribute>
            <name>Closed</name>
            <default_value>false</default_value>
            <restriction useAsDefault="true">
                <evaluator_attributes>
                    <source>roads</source>
                    <direction>From-To</direction>
                    <Field script_type="VBScript">
                        <expression>restricted</expression>
                        <pre_logic>
                            <![CDATA[
                            restricted = False
                            If [osm_construct] = "yes" OR [osm_proposed] = "yes" Then
                                restricted = True
                            End If
                            ]]>
                        </pre_logic>
                    </Field>
                </evaluator_attributes>
                <evaluator_attributes>
                    <source>roads</source>
                    <direction>To-From</direction>
                    <Field script_type="VBScript">
                        <expression>restricted</expression>
                        <pre_logic>
                            <![CDATA[
                            restricted = False
                            If [osm_construct] = "yes" OR [osm_proposed] = "yes" Then
                                restricted = True
                            End If
                            ]]>
                        </pre_logic>
                    </Field>
                </evaluator_attributes>
            </restriction>
        </network_attribute>

        <!-- OneWay - restriction -->
        <network_attribute>
            <name>Oneway</name>
            <default_value>false</default_value>
            <restriction useAsDefault="true">
                <evaluator_attributes>
                    <source>roads</source>
                    <direction>From-To</direction>
                    <Field script_type="VBScript">
                        <expression>restricted</expression>
                        <pre_logic>
                            <![CDATA[
                            restricted = False
                            Select Case LCase([osm_oneway])
                                Case "yes", "true", "1"
                                    restricted = True
                            End Select
                            ]]>
                        </pre_logic>
                    </Field>
                </evaluator_attributes>
                <evaluator_attributes>
                    <source>roads</source>
                    <direction>To-From</direction>
                    <Field script_type="VBScript">
                        <expression>restricted</expression>
                        <pre_logic>
                            <![CDATA[
                            restricted = False
                            Select Case LCase([osm_oneway])
                                Case "-1", "reverse"
                                    restricted = True
                            End Select
                            ]]>
                        </pre_logic>
                    </Field>
                </evaluator_attributes>
            </restriction>
        </network_attribute>

        <!-- TurnRestriction - restriction -->
        <network_attribute>
            <name>TurnRestriction</name>
            <default_value>0</default_value>
            <restriction useAsDefault="true">
                <evaluator_attributes>
                    <source>turns</source>
                    <direction>From-To</direction>
                    <Constant>
                        <value>true</value>
                    </Constant>
                </evaluator_attributes>
            </restriction>
        </network_attribute>

        <!-- HeightRestriction - restriction-->
        <network_attribute>
            <name>HeightRestriction</name>
            <default_value>0</default_value>
            <restriction useAsDefault="false">
                <parameter>
                    <name>Height</name>
                    <datatype>double</datatype>
                    <default_value>0</default_value>
                </parameter>
                <evaluator_attributes>
                    <source>roads</source>
                    <direction>From-To</direction>
                    <Script script_type="VBScript">
                        <expression>restricted</expression>
                        <pre_logic>
                            <![CDATA[
                            restricted = False
                            If ParameterValueByName("Height") > Edge.AttributeValueByName("MaxHeight") Then
                                restricted = True
                            End If
                            ]]>
                        </pre_logic>
                    </Script>
                </evaluator_attributes>
                <evaluator_attributes>
                    <source>roads</source>
                    <direction>To-From</direction>
                    <Script script_type="VBScript">
                        <expression>restricted</expression>
                        <pre_logic>
                            <![CDATA[
                            restricted = False
                            If ParameterValueByName("Height") > Edge.AttributeValueByName("MaxHeight") Then
                                restricted = True
                            End If
                            ]]>
                        </pre_logic>
                    </Script>
                </evaluator_attributes>
            </restriction>
        </network_attribute>

        <!-- Heirarchy -->
        <network_attribute>
            <name>Hierachy</name>
            <default_value>0</default_value>
            <hierachy useAsDefault="false">
                <evaluator_attributes>
                    <source>roads</source>
                    <direction>From-To</direction>
                    <Field script_type="VBScript">
                        <expression>h_level</expression>
                        <pre_logic>
                            <![CDATA[
                            h_level = 4
                            Select Case LCase([highway])
                                Case "motorway", "motorway_link"
                                    h_level = 1
                                Case "trunk", "trunk_link"
                                    h_level = 2
                                Case "primary", "primary_link"
                                    h_level = 3
                                Case "secondary", "secondary_link"
                                    h_level = 4
                                Case "tertiary", "tertiary_link", "living_street", "residential"
                                    h_level = 5
                            End Select
                            ]]>
                        </pre_logic>
                    </Field>
                </evaluator_attributes>
                <evaluator_attributes>
                    <source>roads</source>
                    <direction>To-From</direction>
                    <Field script_type="VBScript">
                        <expression>h_level</expression>
                        <pre_logic>
                            <![CDATA[
                            h_level = 4
                            Select Case LCase([highway])
                                Case "motorway", "motorway_link"
                                    h_level = 1
                                Case "trunk", "trunk_link"
                                    h_level = 2
                                Case "primary", "primary_link"
                                    h_level = 3
                                Case "secondary", "secondary_link"
                                    h_level = 4
                                Case "tertiary", "tertiary_link", "living_street", "residential"
                                    h_level = 5
                            End Select
                            ]]>
                        </pre_logic>
                    </Field>
                </evaluator_attributes>
            </hierachy>
        </network_attribute>
    </network>
</networkConfiguration>
